BUGFIX: template-no-redundant-role — case-insensitive match + <select>→combobox#2727
Draft
johanrd wants to merge 6 commits intoember-cli:masterfrom
Draft
BUGFIX: template-no-redundant-role — case-insensitive match + <select>→combobox#2727johanrd wants to merge 6 commits intoember-cli:masterfrom
johanrd wants to merge 6 commits intoember-cli:masterfrom
Conversation
…x mapping Two changes. 1. Compare role tokens case-insensitively. ARIA role values are ASCII-case-insensitive (HTML-AAM inherits HTML's attribute-comparison semantics). Before: <body role="DOCUMENT"> was not flagged because "DOCUMENT" didn't match "document" in ROLE_TO_ELEMENTS. 2. Add 'combobox' → ['select'] mapping. <select> without `multiple` or `size > 1` has an implicit role of "combobox" per HTML-AAM §4.1. Before: <select role="combobox"> was silently accepted as a redundant role. Two new invalid tests cover the fixes.
Per HTML-AAM, <select>'s implicit role is "combobox" only when neither `multiple` nor `size > 1` is present; otherwise it is "listbox". The previous commit added `combobox: ['select']` unconditionally, which caused false positives for <select role="combobox" multiple> and <select role="combobox" size="5"> (where combobox disagrees with the implicit listbox role and therefore is not redundant). Add a selectHasComboboxImplicitRole helper mirroring jsx-a11y's src/util/implicitRoles/select.js, and short-circuit the redundancy check for <select role="combobox"> when the implicit role is actually listbox. Update the code comment on the `combobox: ['select']` entry to reflect this (and drop the inaccurate "§4.1" reference — the <select> mapping lives in the HTML-AAM main conformance table, section 4, without a numbered subsection). Tests: - valid: <select role="combobox" multiple></select> - valid: <select role="combobox" size="5"></select> - invalid: <select role="combobox" size="1"></select> (size=1 → combobox) - invalid: <select role="COMBOBOX"></select> (case + implicit)
…ases
Translates 35 cases from peer-plugin rules:
- jsx-a11y no-redundant-roles
- vuejs-accessibility no-redundant-roles
- lit-a11y no-redundant-role
Fixture documents parity after this fix:
- Case-insensitive role comparison (body role="DOCUMENT" now flagged).
- Default <select role="combobox"> flagged; <select multiple>/size>1 still
valid (implicit listbox, not combobox).
Remaining divergences (ul/ol role="list", <a role="link"> without href)
are annotated inline. Not wired into the default vitest run.
This was referenced Apr 21, 2026
- Normalize role via trim() + first-token split before lookup so values
like 'COMBOBOX' or 'combobox listbox' are handled consistently
(ARIA role attribute is a space-separated fallback list; only the
first supported token is effective).
- getSelectImplicitRole() now returns 'combobox' | 'listbox' | 'unknown'.
A dynamic <select size={{...}}> previously fell through as 'combobox'
and produced false positives on role="combobox"; we now bail on
'unknown' instead of flagging.
df79aaf to
00c823d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two fixes in one PR (shared rule, no semantic overlap).
1. Case-insensitive role comparison
<body role="DOCUMENT">slipped through.Fix: lowercase the role value before the
ROLE_TO_ELEMENTS/LANDMARK_ROLESlookups.2.
<select>maps to combobox (conditional)<select>has an implicit role of combobox only when neithermultiplenorsize > 1is set; otherwise the implicit role is listbox. Both mappings are documented in the spec.ROLE_TO_ELEMENTSonly listedlistbox: ['select'].<select role="combobox">was silently accepted.Fix: add
combobox: ['select'], and gate the combobox redundancy check on themultiple/sizeattributes so<select role="combobox" multiple>and<select role="combobox" size="5">are not falsely flagged. The implicit-role check mirrors jsx-a11y'ssrc/util/implicitRoles/select.js.Tests cover both fixes, including the uppercase + conditional-combobox interaction.
Prior art
Verified each peer in source:
no-redundant-rolesgetExplicitRole(lowercases viarole.toLowerCase()atsrc/util/getExplicitRole.js:18–23);src/util/implicitRoles/select.js:9–17honorsmultipleandsize > 1.no-redundant-rolesimplicitRoleSet.includes(explicitRole)); no lowercasing in the rule or its utils.<body role="DOCUMENT">is not flagged there either.valid-aria,role-has-required-aria, and related ARIA-validity rules, but no redundant-role check. Role-vs-implicit-role redundancy is not audited.no-redundant-rolegetExplicitRole-style pattern as jsx-a11y (case-insensitive via its ownlib/utils/getExplicitRole.js:11–12).Audit fixture
Translated peer-plugin test fixture at
tests/audit/no-redundant-roles/peer-parity.js. Not wired into the default test run.